package com.zhang.controller;


import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.zhang.common.lang.Result;
import com.zhang.entity.SysRole;
import com.zhang.entity.SysRoleMenu;
import com.zhang.entity.SysUserRole;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author 张立松
 * @since 2022-12-22
 */
@RestController
@RequestMapping("/sys/role")
public class SysRoleController extends BaseController{

    //获取单个角色信息
    @GetMapping("/info/{id}")
    public Result getRoleInfo(@PathVariable("id") Long id){
        SysRole role = sysRoleService.getById(id);
        List<SysRoleMenu> roleMenus = sysRoleMenuService.list(new QueryWrapper<SysRoleMenu>().eq("role_id", id));
        List<Long> menuIds = roleMenus.stream().map(r -> r.getMenuId()).collect(Collectors.toList());//流的方式收集menuId
        role.setMenuIds(menuIds);
        return Result.succ(role);
    }

    //获取所有角色信息列表
    @GetMapping("/list")
    @PreAuthorize("hasAuthority('sys:role:list')")
    public Result getRoleList(@RequestParam(value = "name",required = false) String name){
        IPage<SysRole> pageRole = sysRoleService.page(getPage(),    //获取分页封装类，方法在父类BaseController中
                new QueryWrapper<SysRole>().like(StrUtil.isNotBlank(name),"name",name));//name不为空才加入此条件(通过搜索功能获取列表)
        return Result.succ(pageRole);
    }

    //保存新增的角色信息
    @PostMapping("/save")
    @PreAuthorize("hasAuthority('sys:role:save')")
    public Result saveRoleInfo(@Validated @RequestBody SysRole role){   //加了@Validated注解，validation工具包会进行数据校验
        role.setCreated(LocalDateTime.now());
        sysRoleService.save(role);
        return Result.succ(role);
    }

    //更新修改的角色信息
    @PostMapping("/update")
    @PreAuthorize("hasAuthority('sys:role:update')")
    public Result updateRoleInfo(@Validated @RequestBody SysRole role){   //加了@Validated注解，validation工具包会进行数据校验
        role.setUpdated(LocalDateTime.now());
        sysRoleService.updateById(role);
        //★★角色信息改变一定要清除与此角色相关的用户权限缓存以便更新权限
        sysUserService.clearUserAuthorityInfoByRoleId(role.getId());
        return Result.succ(role);
    }

    //删除角色信息
    @PostMapping("/delete")
    @Transactional  //使用数据库的事务机制，数据要么全部操作成功，要么全不成功
    @PreAuthorize("hasAuthority('sys:role:delete')")
    public Result deleteRolesInfo(@RequestBody Long[] roleIds){
        sysRoleService.removeByIds(Arrays.asList(roleIds));
        //中间表相关记录也要删除
        sysRoleMenuService.remove(new QueryWrapper<SysRoleMenu>().in("role_id",roleIds));
        sysUserRoleService.remove(new QueryWrapper<SysUserRole>().in("role_id",roleIds));
        //★★角色被删除一定要清除与此角色相关的用户权限缓存以便更新权限
        Arrays.stream(roleIds).forEach(roleId->sysUserService.clearUserAuthorityInfoByRoleId(roleId));
        return Result.succ("删除成功");
    }

    //分配角色的权限
    @PostMapping("/perm/{roleId}")
    @Transactional  //使用数据库的事务机制，数据要么全部操作成功，要么全不成功
    @PreAuthorize("hasAuthority('sys:role:perm')")
    public Result setRolePerms(@PathVariable("roleId") Long roleId,@RequestBody Long[] menuIds){
        sysRoleMenuService.remove(new QueryWrapper<SysRoleMenu>().eq("role_id",roleId));    //先删除原来的角色权限
        Arrays.stream(menuIds).forEach(menuId->{
            sysRoleMenuService.save(new SysRoleMenu(roleId,menuId));
        });
        //★★角色权限改变一定要清除与此角色相关的用户权限缓存以便更新权限
        sysUserService.clearUserAuthorityInfoByRoleId(roleId);
        return Result.succ("操作成功");
    }

}

